﻿using Arction.Wpf.BindableCharting.SeriesXY;
using Arction.Wpf.BindableCharting.SeriesPolar;
using Prism.Unity;
using System;
using Arction.Wpf.BindableCharting;
using System.Windows.Media;
using Arction.Wpf.BindableCharting.Titles;
using System.Linq;
using ReactiveUI.Fody.Helpers;
using ReactiveUI;

namespace WPF_UI_Lightningchart.Helper
{
    public class AmpPhaProcessor : ReactiveObject
    {
        private const int MaxPoints = 100;

        private static readonly Color[] colorArray = new Color[]
        {
                    Color.FromArgb(255, 255, 0, 0),    // 红色
                    Color.FromArgb(255, 0, 255, 0),    // 绿色
                    Color.FromArgb(255, 30, 144, 255), // 深蓝色
                    Color.FromArgb(255, 255, 165, 0),  // 橙色
                    Color.FromArgb(255, 75, 0, 130),   // 靛蓝色
                    Color.FromArgb(255, 238, 130, 238),// 紫罗兰
                    Color.FromArgb(255, 255, 69, 0),   // 橙红色
                    Color.FromArgb(255, 60, 179, 113), // 海绿色
                    Color.FromArgb(255, 255, 105, 180),// 热粉色
                    Color.FromArgb(255, 128, 0, 0)     // 栗色
        };

        [Reactive] public LineStyle LineStyle { get; set; }
        [Reactive] public PointShapeStyle PointStyle { get; set; }
        [Reactive] public PointLineSeries AmplitudeSeries { get; set; }
        [Reactive] public PointLineSeries PhaseSeries { get; set; }
        [Reactive] public PointLineSeriesPolar PolarSeries { get; set; }

        public AmpPhaProcessor(string title)
        {
            // 初始化样式
            int sensorIndex = int.TryParse(new string(title.Where(char.IsDigit).ToArray()), out int index) ? index : 1;
            InitializeSeries(sensorIndex,title);
        }

        private void InitializeSeries(int sensorIndex, string title)
        {
            var color = colorArray[(sensorIndex - 1) % colorArray.Length];
            LineStyle = new LineStyle { Color = color };
            PointStyle = new PointShapeStyle { Color1 = color, GradientFill = GradientFillPoint.Linear, Height = 5f, Width = 5f };
            AmplitudeSeries = CreatePointLineSeries(title);
            PhaseSeries = CreatePointLineSeries(title);
            PolarSeries = CreatePointLineSeriesPolar(title);
        }

        private PointLineSeries CreatePointLineSeries(string title)
        {
            return new PointLineSeries
            {
                Points = new SeriesPointCollection(),
                Title = new SeriesTitle { Text = title },
                LineStyle = LineStyle
            };
        }

        private PointLineSeriesPolar CreatePointLineSeriesPolar(string title)
        {
            return new PointLineSeriesPolar
            {
                Points = new PolarSeriesPointCollection(),
                PointsVisible = true,
                PointStyle = PointStyle,
                Title = new RoundSeriesTitle { Text = title, Visible = false },
                LineStyle = LineStyle,
                MouseInteraction = false,

            };
        }

        public void UpdateXYSeries(double speed, double amplitude, double phase)
        {
            UpdateSeries(AmplitudeSeries, speed, amplitude);
            UpdateSeries(PhaseSeries, speed, phase);
        }

        public void UpdatePolarSeries(double amplitude, double angle)
        {
            PrismApplication.Current.Dispatcher.BeginInvoke((Action)(() =>
            {
                PolarSeries.Points.Add(new PolarSeriesPoint { Amplitude = amplitude, Angle = angle });
                if (PolarSeries.Points.Count > MaxPoints)
                    PolarSeries.Points.RemoveAndDispose(0);
            }));
        }

        private void UpdateSeries(PointLineSeries series, double x, double y)
        {
            PrismApplication.Current.Dispatcher.BeginInvoke((Action)(() =>
            {
                series.Points.Add(new SeriesPoint { X = x, Y = y });
                if (series.Points.Count > MaxPoints)
                    series.Points.RemoveAndDispose(0);
            }));
        }
    }
}
